package javango.util;

import java.lang.reflect.InvocationTargetException;
import java.util.IllegalFormatException;
import java.util.Map;
import java.util.MissingFormatArgumentException;

import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.lang.StringUtils;

public class StringFormat {

	public static String format(String format, Map<String, Object> args) throws IllegalFormatException {
		StringBuilder newFormat = new StringBuilder();
		
		int start = 0;
		int loc = format.indexOf("%(");
		Object[] newArgs = new Object[StringUtils.countMatches(format, "%(")];
		int argCount = 0;
		while (loc != -1) {
			loc++;
			newFormat.append(format.substring(start, loc));
			int end = format.indexOf(")", loc);
			String argName = format.substring(loc+1, end);
			if (!args.containsKey(argName)) {
				throw new MissingFormatArgumentException(argName);
			}
			Object value = args.get(argName);
			newArgs[argCount++] = value;
			start = end+1;
			loc = format.indexOf("%(", start);
		}
		newFormat.append(format.substring(start));
		return String.format(newFormat.toString(), newArgs);
	}
		
	public static String format(String format, Object argBean) throws IllegalFormatException {
		StringBuilder newFormat = new StringBuilder();
		
		int start = 0;
		int loc = format.indexOf("%(");
		Object[] newArgs = new Object[StringUtils.countMatches(format, "%(")];
		int argCount = 0;
		while (loc != -1) {
			loc++;
			newFormat.append(format.substring(start, loc));
			int end = format.indexOf(")", loc);
			String argName = format.substring(loc+1, end);
			
			if ( !PropertyUtils.isReadable(argBean, argName)) {
				throw new MissingFormatArgumentException(argName);
			}
			try {
				Object value = PropertyUtils.getProperty(argBean, argName);
				newArgs[argCount++] = value;
			} catch (InvocationTargetException e) {
				throw new MissingFormatArgumentException("Exception while getting: (InvocationTargetException)" + argName);
			} catch (IllegalAccessException e) {
				throw new MissingFormatArgumentException("Exception while getting: (IllegalAccessException)" + argName);
			} catch (NoSuchMethodException e) {
				throw new MissingFormatArgumentException("Exception while getting: (NoSuchMethodException)" + argName);
			}
			start = end+1;
			loc = format.indexOf("%(", start);
		}
		newFormat.append(format.substring(start));
		return String.format(newFormat.toString(), newArgs);		
	}
	
}
